use tokio::sync::oneshot;

use crate::app_state::state::SharedState;
use crate::types::channel::{Request, Response};

pub async fn send_to_rauth_grpc_client_and_wait(
    state: SharedState,
    r: Request,
) -> Result<Response, String> {
    let (rsp_tx, rsp_rx) = oneshot::channel::<Response>();
    state
        .tx_to_rauth_grpc_channel
        .send((r, rsp_tx))
        .await
        .unwrap();

    match rsp_rx.await {
        Ok(rsp) => {
            if let Response::Error(err) = rsp {
                Err(err)
            } else {
                Ok(rsp)
            }
        },
        Err(err) => Err(err.to_string()),
    }
}

pub async fn send_to_iblog_grpc_client_and_wait(
    state: SharedState,
    r: Request,
) -> Result<Response, String> {
    let (rsp_tx, rsp_rx) = oneshot::channel::<Response>();
    state
        .tx_to_iblog_grpc_channel
        .send((r, rsp_tx))
        .await
        .unwrap();

    match rsp_rx.await {
        Ok(rsp) => {
            if let Response::Error(err) = rsp {
                Err(err)
            } else {
                Ok(rsp)
            }
        },
        Err(err) => Err(err.to_string()),
    }
}

pub async fn send_to_redis_client_and_wait(
    state: SharedState,
    r: Request,
) -> Result<Response, String> {
    let (rsp_tx, rsp_rx) = oneshot::channel::<Response>();
    state.tx_to_redis_channel.send((r, rsp_tx)).await.unwrap();

    match rsp_rx.await {
        Ok(rsp) => {
            if let Response::Error(err) = rsp {
                Err(err)
            } else {
                Ok(rsp)
            }
        },
        Err(err) => Err(err.to_string()),
    }
}
